package values.tech
{
import com.adobe.utils.DictionaryUtil;

import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.utils.Dictionary;

import utils.PropertyUtil;

import values.avatar.IPropertyProvider;
import values.common.SimplePlayerValue;
import values.events.TechValueEvent;

[Event(name="levelUp", type="values.events.TechValueEvent")]
[Event(name="unlock", type="values.events.TechValueEvent")]
/**
 * AvatarTechValue
 * @author jliang
 *
 */
public class PlayerTechValue extends EventDispatcher implements IPropertyProvider
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function PlayerTechValue()
	{
		super();
	}
	//==========================================================================
	//  Properties
	//==========================================================================
	protected var techs:Dictionary = new Dictionary(true); /* TechValue */
	
	public function get techList():Array
	{
		var list:Array = DictionaryUtil.getValues(techs);
		list.sortOn("index", Array.NUMERIC);		
		return list;
	}
	
	protected var _maxHP:Number = 0;
	
	[Prop(mapping="maxHP")]
	public function get maxHP():Number
	{
		return _maxHP;
	}
	
	protected var _initMP:Number = 0;
	
	[Prop(mapping="initMp")]
	public function get initMP():Number
	{
		return _initMP;
	}
	
	protected var _mpRecover:Number = 0;
	
	[Prop(mapping="mpRecover")]
	public function get mpRecover():Number
	{
		return _mpRecover;
	}
	
	protected var _normalPower:Number = 0;
	
	[Prop(mapping="normalPower")]
	public function get normalPower():Number
	{
		return _normalPower;
	}
	
	protected var _skillPower:Number = 0;
	
	[Prop(mapping="skillPower")]
	public function get skillPower():Number
	{
		return _skillPower;
	}
	
	protected var _elementPower:Number = 0;
	
	[Prop(mapping="elementPower")]
	public function get elementPower():Number
	{
		return _elementPower;
	}
	
	protected var _normalDefense:Number = 0;
	
	[Prop(mapping="normalDefense")]
	public function get normalDefense():Number
	{
		return _normalDefense;
	}
	
	protected var _skillDefense:Number = 0;
	
	[Prop(mapping="skillDefense")]
	public function get skillDefense():Number
	{
		return _skillDefense;
	}
	
	protected var _elementDefense:Number = 0;
	
	[Prop(mapping="elementDefense")]
	public function get elementDefense():Number
	{
		return _elementDefense;
	}
	
	protected var _normalDamage:Number = 0;
	
	[Prop(mapping="normalDamage")]
	public function get normalDamage():Number
	{
		return _normalDamage;
	}
	
	protected var _skillDamage:Number = 0;
	
	[Prop(mapping="skillDamage")]
	public function get skillDamage():Number
	{
		return _skillDamage;
	}
	
	protected var _elementDamage:Number = 0;
	
	[Prop(mapping="elementDamage")]
	public function get elementDamage():Number
	{
		return _elementDamage;
	}
	
	protected var _moveCapability:Number = 0;
	
	[Prop(mapping="moveCapability")]
	public function get moveCapability():Number
	{
		return _moveCapability;
	}
	
	protected var _hitRate:Number = 0;
	
	[Prop(mapping="hitRate")]
	public function get hitRate():Number
	{
		return _hitRate;
	}
	
	protected var _dodgeRate:Number = 0;
	
	[Prop(mapping="dodgeRate")]
	public function get dodgeRate():Number
	{
		return _dodgeRate;
	}
	
	protected var _penetrateRate:Number = 0;
	
	[Prop(mapping="penetrateRate")]
	public function get penetrateRate():Number
	{
		return _penetrateRate;
	}
	
	protected var _resistRate:Number = 0;
	
	[Prop(mapping="resistRate")]
	public function get resistRate():Number
	{
		return _resistRate;
	}
	
	protected var _enforceRate:Number = 0;
	
	[Prop(mapping="enforceRate")]
	public function get enforceRate():Number
	{
		return _enforceRate;
	}
	
	protected var _blockRate:Number = 0;
	
	[Prop(mapping="blockRate")]
	public function get blockRate():Number
	{
		return _blockRate;
	}
	
	protected var _blockEffect:Number = 0;
	
	[Prop(mapping="blockEffect")]
	public function get blockEffect():Number
	{
		return _blockEffect;
	}
	
	protected var _toughness:Number = 0;
	
	[Prop(mapping="toughness")]
	public function get toughness():Number
	{
		return _toughness;
	}
	
	protected var _critRate:Number = 0;
	
	[Prop(mapping="critRate")]
	public function get critRate():Number
	{
		return _critRate;
	}
	
	protected var _critEffect:Number = 0;
	
	[Prop(mapping="critEffect")]
	public function get critEffect():Number
	{
		return _critEffect;
	}
	
	protected var _defenseRate:Number = 0;
	
	[Prop(mapping="defenseRate")]
	public function get defenseRate():Number
	{
		return _defenseRate;
	}
	
	protected var _suppressRate:Number = 0;
	
	[Prop(mapping="suppressRate")]
	public function get suppressRate():Number
	{
		return _suppressRate;
	}
	
	protected var _suppressEffect:Number = 0;
	
	[Prop(mapping="suppressEffect")]
	public function get suppressEffect():Number
	{
		return _suppressEffect;
	}
	
	protected var _actRate:Number = 0;
	
	[Prop(mapping="actRate")]
	public function get actRate():Number
	{
		return _actRate;
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	/**
	 * [ [科技ID, 1 (等级), 1 (0/1 是否开启)], ..... ] 
	 * @param params
	 * 
	 */	
	public function initialize(params:Array):void
	{
		for each (var obj:Array in params)
		{
			var vo:TechValue = new TechValue();
			vo.initialize(TechTemplateValueList.getByKey(obj[0]), obj[1], (int(obj[2]) == 1 ? true : false));
			
			vo.addEventListener(TechValueEvent.LEVEL_UP, techLevelUpHandler);
			vo.addEventListener(TechValueEvent.UNLOCK, techUnlockHandler);
			
			techs[vo.key] = vo;
		}
		
		init();
	}
	
	public function dispose():void
	{
		for each (var vo:TechValue in techs)
		{
			vo.removeEventListener(TechValueEvent.LEVEL_UP, techLevelUpHandler);
			vo.removeEventListener(TechValueEvent.UNLOCK, techUnlockHandler);
		}
		
		techs = null;
	}
	
	public function getTechByKey(key:String):TechValue
	{
		return techs[key];
	}
	//==========================================================================
	//  Protected methods
	//==========================================================================
	protected function init():void
	{
		var mappingList1:Dictionary = PropertyUtil.initPropertyMapping(this);
		for each (var obj1:Object in mappingList1)
		{
			this["_" + obj1.prop] = 0;
		}
		
		for each (var vo:TechValue in techs)
		{
			if (!vo.isUnlocked) continue;
			
			var mappingList2:Dictionary = PropertyUtil.initPropertyMapping(vo);
			
			for each (var obj2:Object in mappingList2)
			{
				var temp:Number = vo[obj2.prop];
				if (temp == 0) continue;
				
				this["_" + obj2.mapping] += temp;
			}
		}
	}
	//==========================================================================
	//  Event handlers
	//==========================================================================
	protected function techLevelUpHandler(event:TechValueEvent):void
	{
		var vo:TechValue = event.target as TechValue;
		var oldLvl:int = event.params.oldValue;
		
		var changedProperties:Vector.<String> = new Vector.<String>;
		
		var mappingList:Dictionary = PropertyUtil.initPropertyMapping(vo);
		for each (var obj:Object in mappingList)
		{
			var temp:Number = vo[obj.prop];
			if (temp == 0) continue;
			
			this["_" + obj.mapping] += temp;
			
			if (oldLvl > 0)
			{
				temp = vo.getLevelProperty(oldLvl, obj.field);
				this["_" + obj.mapping] -= temp;
			}
			
			changedProperties.push(obj.mapping);
		}
		
		var evt:TechValueEvent = new TechValueEvent(TechValueEvent.LEVEL_UP);
		evt.params = event.params;		
		evt.params.changedProperties = changedProperties;
		
		this.dispatchEvent(evt);
	}
	
	protected function techUnlockHandler(event:TechValueEvent):void
	{
		var vo:TechValue = event.target as TechValue;
		vo.removeEventListener(TechValueEvent.UNLOCK, techUnlockHandler);
		/*
		var changedProperties:Vector.<String> = new Vector.<String>;
		
		var mappingList:Dictionary = PropertyUtil.initPropertyMapping(TechValue);
		for each (var obj:Object in mappingList)
		{
			var temp:Number = vo[obj.prop];
			if (temp == 0) continue;
			
			this["_" + obj.mapping] += temp;
			
			changedProperties.push(obj.mapping);
		}
		
		event.params.changedProperties = changedProperties;
		*/
		var evt:TechValueEvent = new TechValueEvent(TechValueEvent.UNLOCK);
		evt.params = event.params;		
		this.dispatchEvent(evt);
	}
}
}



